import type { CheckboxOption } from '../../../../../components/checkbox/types'
import type { MenuItem } from '../../../../../components/toolbar/types'
import type { GreasyForkElements } from '../../../../../types/constants/personalization/greasy_fork'
import type { ComponentStyleIdType } from '../../../../../types/interfaces'
import type { IUserData } from '../../../../../user_center/tab/personalization/custom_css/theme/others/greasy_fork/module/script_processor/types.ts'
import type {
  ActionHandler,
  FeedbackActionType,
  GreasyForkStorageCategory,
} from '../../../../../user_center/tab/personalization/custom_css/theme/others/greasy_fork/module/storage_process/types'
import type { FeedbackTagLabelsType } from '../../../../../user_center/tab/personalization/custom_css/theme/others/greasy_fork/page/lib/types'
import { Checkbox } from '../../../../../components/checkbox'
import { Filter } from '../../../../../components/filter'
import { Toolbar } from '../../../../../components/toolbar'
import { BaseModule } from '../../../../../lib/abstract'
import { PageHandler } from '../../../../../lib/page_handler'
import { ToolKit } from '../../../../../lib/utils/toolkit'
import {
  AppStyleCollections,
  BodyClasses,
  ComponentStyleId,
  generateHideSelector,
  logger,
  MODULE_CONFIG,
  PAGE_ELEMENTS,
  RATING_BACKGROUND_COLORS,
  SUPPORTED_PLATFORMS,
} from '../../../../../types/constants'
import { getElementSelector } from '../../../../../types/constants/personalization/common'
import { SYMBOLS } from '../../../../../types/interfaces'
import {
  FeedbackClearOperationType,
  FeedbackTagType,
  FeedbackToolbarCategory,
  GreasyForkUserType,
  ResolutionStatusType,
  UpdateOperation,
} from '../../../../../user_center/tab/personalization/custom_css/theme/others/greasy_fork/module/storage_process/types'
import { USER_TAG_LABELS } from '../../../../../user_center/tab/personalization/custom_css/theme/others/greasy_fork/page/lib/types'
import { ConfigManager } from '../../../../config_manager'
import { GreasyForkFeedbackGroup } from '../../../data_presentation/platform/greasy_fork/feedback_group'
import { FeedbackDataMarkerType } from '../../../data_presentation/platform/greasy_fork/script_valuation/types'

export const FEEDBACK_TAG_LABELS: FeedbackTagLabelsType = {
  // 用户类型标签
  ...USER_TAG_LABELS,

  // 内容分类标签
  [FeedbackTagType.Problem]: {
    value: FeedbackTagType.Problem,
    label: '问题',
    icon: SYMBOLS.OTHERS.BUG,
    bgColor: 'linear-gradient(135deg, #FF5722, #FF9800)',
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },
  [FeedbackTagType.Suggestion]: {
    value: FeedbackTagType.Suggestion,
    label: '建议',
    icon: SYMBOLS.OTHERS.LIGHT_BULB,
    bgColor: 'linear-gradient(135deg, #2196F3, #03A9F4)',
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },
  [FeedbackTagType.Praise]: {
    value: FeedbackTagType.Praise,
    label: '好评',
    icon: SYMBOLS.OTHERS.LIKE,
    bgColor: RATING_BACKGROUND_COLORS.good.color,
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },
  [FeedbackTagType.Neutral]: {
    value: FeedbackTagType.Neutral,
    label: '一般',
    icon: SYMBOLS.OTHERS.NEUTRAL,
    bgColor: RATING_BACKGROUND_COLORS.ok.color,
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },
  [FeedbackTagType.Negative]: {
    value: FeedbackTagType.Negative,
    label: '差评',
    icon: SYMBOLS.OTHERS.DISLIKE,
    bgColor: RATING_BACKGROUND_COLORS.bad.color,
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },
  [FeedbackTagType.Malicious]: {
    value: FeedbackTagType.Malicious,
    label: '恶意',
    icon: SYMBOLS.NETWORK.SHIELD,
    bgColor: 'linear-gradient(135deg, #9C27B0, #E91E63)',
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },
  [FeedbackTagType.Other]: {
    value: FeedbackTagType.Other,
    label: '其他',
    icon: SYMBOLS.MATH.ADD,
    bgColor: 'linear-gradient(135deg, #607D8B, #9E9E9E)',
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },

  // 处理状态标签
  [ResolutionStatusType.Unresolved]: {
    value: ResolutionStatusType.Unresolved,
    label: '未解决',
    icon: SYMBOLS.STATUS.ERROR,
    bgColor: 'linear-gradient(135deg, #d32f2f, #f44336)',
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },
  [ResolutionStatusType.Resolving]: {
    value: ResolutionStatusType.Resolving,
    label: '解决中',
    icon: SYMBOLS.PROGRESS.SPINNER,
    bgColor: 'linear-gradient(135deg, #FF9800, #FFC107)',
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },
  [ResolutionStatusType.PendingVerification]: {
    value: ResolutionStatusType.PendingVerification,
    label: '待验证',
    icon: SYMBOLS.UI.SEARCH,
    bgColor: 'linear-gradient(135deg, #00BCD4, #03A9F4)',
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },
  [ResolutionStatusType.Resolved]: {
    value: ResolutionStatusType.Resolved,
    label: '已解决',
    icon: SYMBOLS.STATUS.SUCCESS,
    bgColor: 'linear-gradient(135deg, #4CAF50, #8BC34A)',
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },
  [ResolutionStatusType.Deferred]: {
    value: ResolutionStatusType.Deferred,
    label: '延期处理',
    icon: SYMBOLS.TIME.CALENDAR,
    bgColor: 'linear-gradient(135deg, #9C27B0, #673AB7)',
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },
  [ResolutionStatusType.OnHold]: {
    value: ResolutionStatusType.OnHold,
    label: '挂起',
    icon: SYMBOLS.UI.PAUSE,
    bgColor: 'linear-gradient(135deg, #607D8B, #9E9E9E)',
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },
  [ResolutionStatusType.Invalid]: {
    value: ResolutionStatusType.Invalid,
    label: '无效',
    icon: SYMBOLS.UI.BLOCK_ALERT,
    bgColor: 'linear-gradient(135deg, #9E9E9E, #757575)',
    textColor: '#ffffff',
    shouldGenerateStyle: true,
  },

  // 清除操作
  [FeedbackClearOperationType.ClearTypes]: {
    value: FeedbackClearOperationType.ClearTypes,
    label: '清除当前',
    icon: SYMBOLS.OTHERS.CLEAR,
    bgColor: '',
    textColor: '',
    shouldGenerateStyle: false,
  },
  [FeedbackClearOperationType.ClearTags]: {
    value: FeedbackClearOperationType.ClearTags,
    label: '清除当前',
    icon: SYMBOLS.OTHERS.CLEAR,
    bgColor: '',
    textColor: '',
    shouldGenerateStyle: false,
  },
  [FeedbackClearOperationType.ClearStatus]: {
    value: FeedbackClearOperationType.ClearStatus,
    label: '清除当前',
    icon: SYMBOLS.OTHERS.CLEAR,
    bgColor: '',
    textColor: '',
    shouldGenerateStyle: false,
  },
  [FeedbackClearOperationType.ClearAllTypes]: {
    value: FeedbackClearOperationType.ClearAllTypes,
    label: '清除所有',
    icon: SYMBOLS.OTHERS.CLEAR,
    bgColor: '',
    textColor: '',
    shouldGenerateStyle: false,
  },
  [FeedbackClearOperationType.ClearAllTags]: {
    value: FeedbackClearOperationType.ClearAllTags,
    label: '清除所有',
    icon: SYMBOLS.OTHERS.CLEAR,
    bgColor: '',
    textColor: '',
    shouldGenerateStyle: false,
  },
  [FeedbackClearOperationType.clearAllStatus]: {
    value: FeedbackClearOperationType.clearAllStatus,
    label: '清除所有',
    icon: SYMBOLS.OTHERS.CLEAR,
    bgColor: '',
    textColor: '',
    shouldGenerateStyle: false,
  },
}

interface CategoryConfig {
  storagePath: GreasyForkStorageCategory
  attrName: FeedbackDataMarkerType
  enumType: object
  clearType: FeedbackClearOperationType
}

const CATEGORY_CONFIG: Record<FeedbackToolbarCategory, CategoryConfig> = {
  [FeedbackToolbarCategory.UserType]: {
    storagePath: 'user.types',
    attrName: FeedbackDataMarkerType.MarkerTypes,
    enumType: GreasyForkUserType,
    clearType: FeedbackClearOperationType.ClearTypes,
  },
  [FeedbackToolbarCategory.ContentTag]: {
    storagePath: 'feedback.tags',
    attrName: FeedbackDataMarkerType.MarkerTags,
    enumType: FeedbackTagType,
    clearType: FeedbackClearOperationType.ClearTags,
  },
  [FeedbackToolbarCategory.ResolutionStatus]: {
    storagePath: 'feedback.status',
    attrName: FeedbackDataMarkerType.MarkerStatus,
    enumType: ResolutionStatusType,
    clearType: FeedbackClearOperationType.ClearStatus,
  },
}

enum ControlsType {
  hideMalicious = 'hideMalicious',
  hideBlacklist = 'hideBlacklist',
  hideNegative = 'hideNegative',
}

interface Config {
  enabled?: boolean
}

export class GreasyForkFeedbackMark extends BaseModule {
  readonly id: string = 'greasy_fork_feedback_mark'
  readonly styleId: string = ComponentStyleId[this.name]
  isInitialized: boolean = false
  readonly supportedPlatforms: string[] = ConfigManager.getInstance().moduleSupportedPlatforms(this.name)

  private static instance: GreasyForkFeedbackMark
  private pageHandler: PageHandler = PageHandler.getInstance()
  private feedbackGroup: GreasyForkFeedbackGroup = GreasyForkFeedbackGroup.getInstance()
  private toolbars = new Map<string, Toolbar>()
  private filter: Filter | null = null
  private checkbox: Checkbox | null = null
  private filterSelectedValues: Record<string, string[]> = {}

  elements: GreasyForkElements = PAGE_ELEMENTS[SUPPORTED_PLATFORMS.GREASY_FORK]
  private readonly containerSelector = getElementSelector(this.elements, 'COMMON_CONTAINER')
  private readonly itemSelector = `.discussion-list-container`
  private readonly itemFullSelector = `${this.containerSelector} ${this.itemSelector}`
  private readonly userLinkSelector = `.discussion-meta > .discussion-meta-item > .user-link`
  private controls: Record<ControlsType, boolean> = {
    [ControlsType.hideNegative]: false,
    [ControlsType.hideMalicious]: false,
    [ControlsType.hideBlacklist]: false,
  }

  private readonly controls_config: CheckboxOption[] = [
    {
      label: '隐藏恶意反馈',
      value: ControlsType.hideMalicious,
      onInit: (checked: boolean) => {
        this.controls.hideMalicious = checked
        this.hideMaliciousFeedback()
      },
    },
    {
      label: '隐藏黑名单用户的反馈',
      value: ControlsType.hideBlacklist,
      onInit: (checked: boolean) => {
        this.controls.hideBlacklist = checked
        this.hideBlacklistFeedback()
      },
    },
    {
      label: '隐藏差评',
      value: ControlsType.hideNegative,
      onInit: (checked: boolean) => {
        this.controls.hideNegative = checked
        this.hideNegativeFeedback()
      },
    },
  ]

  defaultConfig: Config = {
    enabled: true,
  }

  get name(): ComponentStyleIdType {
    return 'GreasyForkFeedbackMark'
  }

  constructor(config?: Config | object) {
    super()

    this.config = {
      ...this.defaultConfig,
      ...config,
    }
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): GreasyForkFeedbackMark {
    if (!GreasyForkFeedbackMark.instance) {
      GreasyForkFeedbackMark.instance = new GreasyForkFeedbackMark()
    }
    return GreasyForkFeedbackMark.instance
  }

  destroy(): void {
    try {
      // 1. 移除所有创建的 DOM 元素
      $('.feedback-tags-container').remove()

      // 2. 清除工具栏实例
      this.toolbars.forEach((toolbar) => {
        toolbar.destroy()
      })
      this.toolbars.clear()

      // 3. 清除筛选器实例
      if (this.filter) {
        this.filter.destroy()
        this.filter = null
      }

      // 4. 清除筛选器选中值
      this.filterSelectedValues = {}

      // 5. 清除控制项实例
      if (this.checkbox) {
        this.checkbox.destroy()
        this.checkbox = null
      }

      // 6. 重置状态
      this.isInitialized = false

      super.destroy()
    }
    catch (error: any) {
      logger.error(`[${this.name}] Error occurred during module destruction:`, error)
    }
    finally {
      // 清理数据属性
      $(this.itemFullSelector).find('.discussion-list-item').removeData('has-toolbar')
    }
  }

  core(): void {
    this.loadConfig()

    if (!this.config.enabled)
      return

    // 渲染工具栏
    this.renderToolbar()
    // 添加标记标签
    this.addTag()
    // 添加控制项
    this.addControls()
    // 最后初始化筛选器
    this.initFilter()
  }

  onToggleCallback(_id: string, checked: boolean): void {
    super.onToggleCallback(_id, checked)
  }

  /**
   * 添加标签
   */
  private addTag() {
    $(this.itemFullSelector).each((_, element) => {
      const $element = $(element)
      const $userLink = $element.find('.discussion-meta > .discussion-meta-item > .user-link')

      // 添加用户头像
      const data: IUserData = {
        author: $userLink.text().trim(),
        authorUrl: $userLink.attr('href') || '',
      }
      this.pageHandler.features.user.addAvatar($element, data)
      const $avatarContainer = $element.find(`.${AppStyleCollections.Body.AVATAR_CONTAINER}`)

      // 处理用户标签
      this.pageHandler.services.greasyFork.handleUserTag($element, this.userLinkSelector, $avatarContainer)

      // 处理其他标签
      this.handleOtherTag($element)
    })
  }

  handleOtherTag($element: JQuery): void {
    const $listItem = $element.find('.discussion-list-item')
    const $indexWrapper = $element.find(`#${BodyClasses.INDEX_CONTAINER}`)
    const hasIndex = $indexWrapper.length > 0

    // 1. 收集所有有效标签（不包含用户标签）
    const currentTags = Object.values(FeedbackDataMarkerType)
      .filter(type => type !== FeedbackDataMarkerType.MarkerTypes)
      .map(marker => $element.attr(marker))
      .filter(Boolean) as string[]

    // 2. 获取或创建标签容器
    let $tagsContainer = $element.find('.feedback-tags-container')
    if ($tagsContainer.length === 0 && currentTags.length > 0) {
      // 初始创建容器
      $tagsContainer = $('<div class="feedback-tags-container"></div>')
      // 插入容器中
      hasIndex ? $indexWrapper.append($tagsContainer) : $listItem.prepend($tagsContainer)
    }
    else if (currentTags.length === 0) {
      // 没有标签时移除容器
      $tagsContainer.remove()
      return
    }

    // 3. 完全重新生成标签（确保与当前状态同步）
    $tagsContainer.empty()

    currentTags.forEach((tag) => {
      const tagConfig = FEEDBACK_TAG_LABELS[tag as keyof typeof FEEDBACK_TAG_LABELS]
      const $tag = $(`
        <span class="feedback-tag ${tag}" style="
          background: ${tagConfig.bgColor}; 
          color: ${tagConfig.textColor};"
        >
          <span class="tag-icon">${tagConfig.icon}</span>
          <span class="tag-text">${tagConfig.label}</span>
        </span>
      `)
      $tagsContainer.append($tag)
    })
  }

  /**
   * 渲染工具栏
   */
  private renderToolbar() {
    const $target = $(this.itemFullSelector).find('.discussion-list-item')

    if (!$target || !$target.length)
      return

    $target.each((_, element) => {
      const $comment = $(element)

      if ($comment.data(BodyClasses.HAS_TOOLBAR))
        return

      // 使用包裹来更新标记
      const $discussion = $comment.closest(this.itemSelector)
      const id = this.getUniqueId($discussion)
      const userId = this.pageHandler.services.greasyFork.getUserId($discussion.find(this.userLinkSelector))

      if (!id || id.length === 0 || !userId || userId.length === 0)
        return

      // 使用评论容器来添加工具栏
      const toolbar = this.initToolbar()
      $comment.append(toolbar.render())
      toolbar.mount($comment)
      $comment.data(BodyClasses.HAS_TOOLBAR, true)

      // 存储工具栏实例
      this.toolbars.set(id, toolbar)

      // 更新标记
      this.updateElementUI($discussion, userId, FeedbackToolbarCategory.UserType)
      this.updateElementUI($discussion, id, FeedbackToolbarCategory.ContentTag)
      this.updateElementUI($discussion, id, FeedbackToolbarCategory.ResolutionStatus)
      // 处理工具栏菜单可见性
      this.handleToolbarMenuVisibility($discussion, id, userId)
    })
  }

  /**
   * 处理工具栏菜单可见性
   */
  private handleToolbarMenuVisibility($element: JQuery, id: string, userId: string): void {
    // 遍历所有分类配置
    Object.entries(CATEGORY_CONFIG).forEach(([_, config]) => {
      // 检查是否存在该分类的标记
      const hasMark = Object.values(
        this.pageHandler.storages.greasyFork.getStatus(config.clearType === FeedbackClearOperationType.ClearTypes ? userId : id, config.storagePath),
      ).some(Boolean)

      // 更新对应清除按钮的显示状态
      $element.find(`.toolbar [data-id="${config.clearType}"]`)
        .toggleClass('deactivate', !hasMark)
    })
  }

  private initFilter(): void {
    // 创建筛选器实例
    this.filter = new Filter({
      id: MODULE_CONFIG.PLATFORM.greasyFork.filterId.feedback,
      filterGroups: [
        {
          id: FeedbackToolbarCategory.UserType,
          label: '用户身份',
          icon: SYMBOLS.UI.TAG,
          selectionMode: 'multiple',
          options: [
            GreasyForkUserType.FeedbackProvider,
            GreasyForkUserType.LoyalFan,
            GreasyForkUserType.ActiveUser,
            GreasyForkUserType.SuperCreator,
            GreasyForkUserType.Blacklisted,
          ].map(key => ({
            label: FEEDBACK_TAG_LABELS[key].label,
            value: key,
            icon: FEEDBACK_TAG_LABELS[key].icon,
          })),
        },
        {
          id: FeedbackToolbarCategory.ContentTag,
          label: '内容分类',
          icon: SYMBOLS.UI.BOOKMARK,
          selectionMode: 'multiple',
          options: [
            FeedbackTagType.Problem,
            FeedbackTagType.Suggestion,
            FeedbackTagType.Praise,
            FeedbackTagType.Neutral,
            FeedbackTagType.Negative,
            FeedbackTagType.Malicious,
            FeedbackTagType.Other,
          ].map(key => ({
            label: FEEDBACK_TAG_LABELS[key].label,
            value: key,
            icon: FEEDBACK_TAG_LABELS[key].icon,
          })),
        },
        {
          id: FeedbackToolbarCategory.ResolutionStatus,
          label: '处理进度',
          icon: SYMBOLS.OTHERS.ROCKET,
          selectionMode: 'multiple',
          options: [
            ResolutionStatusType.Unresolved,
            ResolutionStatusType.Resolving,
            ResolutionStatusType.PendingVerification,
            ResolutionStatusType.Resolved,
            ResolutionStatusType.Deferred,
            ResolutionStatusType.OnHold,
            ResolutionStatusType.Invalid,
          ].map(key => ({
            label: FEEDBACK_TAG_LABELS[key].label,
            value: key,
            icon: FEEDBACK_TAG_LABELS[key].icon,
          })),
        },
      ],
      onChange: (selected) => {
        this.filterSelectedValues = selected
        this.applyFilters()
      },
    })

    // 插入到讨论列表上方
    const $container = $(this.containerSelector)
    $container.find('header h2').before(this.filter.render())

    // 绑定事件
    this.filter.mount($container)

    // 更新选项计数
    Object.values(FeedbackToolbarCategory).forEach((category) => {
      this.filter?.updateOptionCounts(category, this.calculateCounts(category))
    })
  }

  private applyFilters(): void {
    const data = this.filterSelectedValues

    if (!data || Object.keys(data).length === 0)
      return

    // 不包含隐藏元素
    $(this.itemFullSelector).not(generateHideSelector('')).each((_, element) => {
      const $discussion = $(element)

      const hasUserType = FeedbackToolbarCategory.UserType in data
        && (data[FeedbackToolbarCategory.UserType].length === 0
          || data[FeedbackToolbarCategory.UserType].includes($discussion.attr(FeedbackDataMarkerType.MarkerTypes) || ''))

      const hasContentTag = FeedbackToolbarCategory.ContentTag in data
        && (data[FeedbackToolbarCategory.ContentTag].length === 0
          || data[FeedbackToolbarCategory.ContentTag].some((tag) => {
            const matchesTagAttribute = ($discussion.attr(FeedbackDataMarkerType.MarkerTags) || '') === tag

            const matchesRatingIcon
              = (tag === FeedbackTagType.Praise && $discussion.find('.discussion-title .rating-icon-good').length)
                || (tag === FeedbackTagType.Neutral && $discussion.find('.discussion-title .rating-icon-ok').length)
                || (tag === FeedbackTagType.Negative && $discussion.find('.discussion-title .rating-icon-bad').length)

            const matchesOther
              = !$discussion.attr(FeedbackDataMarkerType.MarkerTags) && !matchesRatingIcon
                && tag === FeedbackTagType.Other && !$discussion.find('.discussion-title .rating-icon').length

            return matchesTagAttribute || matchesRatingIcon || matchesOther
          }))

      const hasStatus = FeedbackToolbarCategory.ResolutionStatus in data
        && (data[FeedbackToolbarCategory.ResolutionStatus].length === 0
          || data[FeedbackToolbarCategory.ResolutionStatus].includes($discussion.attr(FeedbackDataMarkerType.MarkerStatus) || ''))

      const hidden = !hasUserType || !hasContentTag || !hasStatus

      // 差评
      const isNegative = this.controls.hideNegative
        && $discussion.attr(FeedbackDataMarkerType.MarkerTags)?.includes(FeedbackTagType.Negative)
      // 恶意
      const isMalicious = this.controls.hideMalicious
        && $discussion.attr(FeedbackDataMarkerType.MarkerTags)?.includes(FeedbackTagType.Malicious)
      // 黑名单
      const isBlacklisted = this.controls.hideBlacklist
        && $discussion.attr(FeedbackDataMarkerType.MarkerTypes)?.includes(GreasyForkUserType.Blacklisted)

      const shouldHide = Boolean(hidden || isNegative || isMalicious || isBlacklisted)
      ToolKit.dom.showControl($discussion, { show: !shouldHide })
    })

    // 更新评论分组
    if (this.feedbackGroup.isInitialized) {
      this.feedbackGroup.refresh()
    }
  }

  private calculateCounts(category: FeedbackToolbarCategory) {
    const counts: Record<string, Record<string, number>> = {}

    // 初始化计数
    Object.values(FeedbackToolbarCategory).forEach((cat) => {
      counts[cat] = {}
    })

    // 不包含隐藏元素
    $(this.itemFullSelector).not(generateHideSelector('')).each((_, element) => {
      const $element = $(element)

      // 统计用户身份
      const userTypes = $element.attr(FeedbackDataMarkerType.MarkerTypes)?.split(',') || []
      userTypes.forEach((type) => {
        counts[FeedbackToolbarCategory.UserType][type] = (counts[FeedbackToolbarCategory.UserType][type] || 0) + 1
      })

      // 统计内容标签
      const tags = $element.attr(FeedbackDataMarkerType.MarkerTags)?.split(',') || []
      tags.forEach((tag) => {
        counts[FeedbackToolbarCategory.ContentTag][tag] = (counts[FeedbackToolbarCategory.ContentTag][tag] || 0) + 1
      })
      // 补充内容标签 - 好评和差评
      if ($element.find('.discussion-title .rating-icon-good').length) {
        counts[FeedbackToolbarCategory.ContentTag][FeedbackTagType.Praise] = (counts[FeedbackToolbarCategory.ContentTag][FeedbackTagType.Praise] || 0) + 1
      }
      if ($element.find('.discussion-title .rating-icon-ok').length) {
        counts[FeedbackToolbarCategory.ContentTag][FeedbackTagType.Neutral] = (counts[FeedbackToolbarCategory.ContentTag][FeedbackTagType.Neutral] || 0) + 1
      }
      if ($element.find('.discussion-title .rating-icon-bad').length) {
        counts[FeedbackToolbarCategory.ContentTag][FeedbackTagType.Negative] = (counts[FeedbackToolbarCategory.ContentTag][FeedbackTagType.Negative] || 0) + 1
      }
      // 补充内容标签 - 其他
      if (!$element.attr(FeedbackDataMarkerType.MarkerTags) && !$element.find('.discussion-title .rating-icon').length) {
        counts[FeedbackToolbarCategory.ContentTag][FeedbackTagType.Other] = (counts[FeedbackToolbarCategory.ContentTag][FeedbackTagType.Other] || 0) + 1
      }

      // 统计处理进度
      const status = $element.attr(FeedbackDataMarkerType.MarkerStatus)?.split(',') || []
      status.forEach((status) => {
        counts[FeedbackToolbarCategory.ResolutionStatus][status] = (counts[FeedbackToolbarCategory.ResolutionStatus][status] || 0) + 1
      })
    })

    return counts[category] || {}
  }

  /**
   * 创建处理函数映射
   * @param enumObj 枚举对象
   * @param category 反馈分类
   */
  private createHandlerMap = <T extends FeedbackActionType>(
    enumObj: Record<string, T>,
    category: FeedbackToolbarCategory,
  ): ActionHandler =>
    Object.values(enumObj).reduce((acc, key) => ({
      ...acc,
      [key]: (event: JQuery.ClickEvent) => {
        this.handleUserAction(event, key, category)
      },
    }), {} as ActionHandler)

  private initToolbar(): Toolbar {
    // 合并所有处理函数
    const actionHandlers: any = {
      ...this.createHandlerMap(GreasyForkUserType, FeedbackToolbarCategory.UserType),
      ...this.createHandlerMap(FeedbackTagType, FeedbackToolbarCategory.ContentTag),
      ...this.createHandlerMap(ResolutionStatusType, FeedbackToolbarCategory.ResolutionStatus),
      ...{
        [FeedbackClearOperationType.ClearTypes]: (event: JQuery.ClickEvent) => {
          this.handleClearAction(event, FeedbackToolbarCategory.UserType)
        },
        [FeedbackClearOperationType.ClearTags]: (event: JQuery.ClickEvent) => {
          this.handleClearAction(event, FeedbackToolbarCategory.ContentTag)
        },
        [FeedbackClearOperationType.ClearStatus]: (event: JQuery.ClickEvent) => {
          this.handleClearAction(event, FeedbackToolbarCategory.ResolutionStatus)
        },
        [FeedbackClearOperationType.ClearAllTypes]: () => {
          this.handleClearAllAction(FeedbackToolbarCategory.UserType)
        },
        [FeedbackClearOperationType.ClearAllTags]: () => {
          this.handleClearAllAction(FeedbackToolbarCategory.ContentTag)
        },
        [FeedbackClearOperationType.clearAllStatus]: () => {
          this.handleClearAllAction(FeedbackToolbarCategory.ResolutionStatus)
        },
      },
    }

    const menus = [
      {
        id: FeedbackToolbarCategory.UserType,
        icon: SYMBOLS.UI.TAG,
        text: '用户身份',
        children: [
          GreasyForkUserType.FeedbackProvider,
          GreasyForkUserType.LoyalFan,
          GreasyForkUserType.ActiveUser,
          GreasyForkUserType.SuperCreator,
          GreasyForkUserType.Blacklisted,
          FeedbackClearOperationType.ClearTypes,
          FeedbackClearOperationType.ClearAllTypes,
        ].map(key => ({
          id: key,
          text: FEEDBACK_TAG_LABELS[key].label,
          icon: FEEDBACK_TAG_LABELS[key].icon,
          onClick: (_menu: MenuItem, event: JQuery.ClickEvent) => {
            actionHandlers[key](event)
          },
        })),
      },
      {
        id: FeedbackToolbarCategory.ContentTag,
        icon: SYMBOLS.UI.BOOKMARK,
        text: '内容分类',
        children: [
          FeedbackTagType.Problem,
          FeedbackTagType.Suggestion,
          FeedbackTagType.Praise,
          FeedbackTagType.Neutral,
          FeedbackTagType.Negative,
          FeedbackTagType.Malicious,
          FeedbackTagType.Other,
          FeedbackClearOperationType.ClearTags,
          FeedbackClearOperationType.ClearAllTags,
        ].map(key => ({
          id: key,
          text: FEEDBACK_TAG_LABELS[key].label,
          icon: FEEDBACK_TAG_LABELS[key].icon,
          onClick: (_menu: MenuItem, event: JQuery.ClickEvent) => {
            actionHandlers[key](event)
          },
        })),
      },
      {
        id: FeedbackToolbarCategory.ResolutionStatus,
        icon: SYMBOLS.OTHERS.ROCKET,
        text: '处理进度',
        children: [
          ResolutionStatusType.Unresolved,
          ResolutionStatusType.Resolving,
          ResolutionStatusType.PendingVerification,
          ResolutionStatusType.Resolved,
          ResolutionStatusType.Deferred,
          ResolutionStatusType.OnHold,
          ResolutionStatusType.Invalid,
          FeedbackClearOperationType.ClearStatus,
          FeedbackClearOperationType.clearAllStatus,
        ].map(key => ({
          id: key,
          text: FEEDBACK_TAG_LABELS[key].label,
          icon: FEEDBACK_TAG_LABELS[key].icon,
          onClick: (_menu: MenuItem, event: JQuery.ClickEvent) => {
            actionHandlers[key](event)
          },
        })),
      },
    ]

    return new Toolbar({
      id: MODULE_CONFIG.PLATFORM.greasyFork.toolbarId.feedback,
      menus,
    })
  }

  /**
   * 处理操作
   */
  private handleUserAction(event: JQuery.ClickEvent, actionType: FeedbackActionType, category: FeedbackToolbarCategory): void {
    const $element = $(event.currentTarget)
    const $discussionItem = $element.closest(this.itemSelector)

    const $userLink = $discussionItem.find(this.userLinkSelector)
    const userId = this.pageHandler.services.greasyFork.getUserId($userLink)
    const id = category === FeedbackToolbarCategory.UserType ? userId : this.getUniqueId($discussionItem)

    const userName = $userLink.text().trim()
    const discussionTitle = $discussionItem.find('.discussion-snippet').text().trim()
    const scriptName = $('#script-info header h2').text().trim()
    const remark = category === FeedbackToolbarCategory.UserType ? userName : `${scriptName}:::${discussionTitle}`

    if (!id || id.length === 0)
      return

    try {
      this.handleAction(this.getToolbarMenuItem(event, category), $discussionItem, actionType, category, id, 'maker', remark)
    }
    catch (error: any) {
      logger.warn(`[${this.name}] ${actionType} 操作失败: ${error.message}`)
    }
  }

  private handleClearAllAction(category: FeedbackToolbarCategory): void {
    $(this.itemFullSelector).each((_, item) => {
      this.handleClearAction($(item), category)
    })
  }

  /**
   * 处理清除操作
   */
  private handleClearAction(target: JQuery.ClickEvent | JQuery<HTMLElement>, category: FeedbackToolbarCategory): void {
    const $element = 'currentTarget' in target
      ? $(target.currentTarget)
      : target
    const $discussionItem = $element.closest(this.itemSelector)

    const $userLink = $discussionItem.find(this.userLinkSelector)
    const userId = this.pageHandler.services.greasyFork.getUserId($userLink)
    const id = category === FeedbackToolbarCategory.UserType ? userId : this.getUniqueId($discussionItem)

    const userName = $userLink.text().trim()
    const discussionTitle = $discussionItem.find('.discussion-snippet').text().trim()
    const scriptName = $('#script-info header h2').text().trim()
    const remark = category === FeedbackToolbarCategory.UserType ? userName : `${scriptName}:::${discussionTitle}`

    if (!id || id.length === 0)
      return

    try {
      this.handleAction(this.getToolbarMenuItem(target, category), $discussionItem, null, category, id, 'clear', remark)
      logger.debug(`[${this.name}] 已清除讨论 id='${id}' 的'${category}'标记`)
    }
    catch (error: any) {
      logger.warn(`[${this.name}] 清除讨论 id='${id}' 的'${category}'标记失败: ${error.message}`)
    }
  }

  /**
   * 更新元素 UI
   */
  private updateElementUI($element: JQuery, id: string, category: FeedbackToolbarCategory): void {
    const config = CATEGORY_CONFIG[category]
    const storageData = this.pageHandler.storages.greasyFork.getStatus(id, config.storagePath)
    const trueConfig = Object.entries(storageData)
      .filter(([_, value]) => value)
      .map(([key]) => key)

    if (trueConfig.length === 0) {
      // 移除数据属性
      $element.removeAttr(config.attrName)
      // 移除用户徽章
      Object.values(GreasyForkUserType).forEach((userType) => {
        $element.find(`.user-badge.${userType}`).remove()
      })
      return
    }

    $element.attr(config.attrName, trueConfig[0])
    this.updateElementVisibility(config.attrName, trueConfig[0])
  }

  /**
   * 更新元素可见性
   */
  updateElementVisibility(label: string, value: string): void {
    if (this.controls.hideNegative && label === FeedbackDataMarkerType.MarkerTags && value === FeedbackTagType.Negative) {
      this.handleControlChange(ControlsType.hideNegative, true)
    }
    else if (this.controls.hideMalicious && label === FeedbackDataMarkerType.MarkerTags && value === FeedbackTagType.Malicious) {
      this.handleControlChange(ControlsType.hideMalicious, true)
    }
    else if (this.controls.hideBlacklist && label === FeedbackDataMarkerType.MarkerTypes && value === GreasyForkUserType.Blacklisted) {
      this.handleControlChange(ControlsType.hideBlacklist, true)
    }
  }

  /**
   * 更新工具栏菜单
   */
  private updateToolbarMenu($submenu: JQuery, category: FeedbackToolbarCategory) {
    const deactivateClassName = 'deactivate'

    // 清除按钮元素（不包含"清空所有"的按钮）
    const excludeTypes = [
      FeedbackClearOperationType.ClearAllTypes,
      FeedbackClearOperationType.ClearAllTags,
      FeedbackClearOperationType.clearAllStatus,
    ]
    const clearSelector = Object.values(FeedbackClearOperationType)
      .filter(item => !excludeTypes.includes(item))
      .map(item => `[data-id="${item}"]`)
      .join(',')
    const $clearElement = $submenu.find(clearSelector)

    // 已标识元素
    let markerSelector = ''
    switch (category) {
      case FeedbackToolbarCategory.UserType:
        markerSelector = `[${FeedbackDataMarkerType.MarkerTypes}]`
        break
      case FeedbackToolbarCategory.ContentTag:
        markerSelector = `[${FeedbackDataMarkerType.MarkerTags}]`
        break
      case FeedbackToolbarCategory.ResolutionStatus:
        markerSelector = `[${FeedbackDataMarkerType.MarkerStatus}]`
        break
    }
    const $item = $submenu.closest(this.itemSelector).filter(markerSelector)

    // 根据是否标识来更新清除按钮显示状态
    $clearElement.toggleClass(deactivateClassName, !$item?.length)
  }

  /**
   * 获取工具栏一级菜单元素
   */
  getToolbarMenuItem(target: JQuery.ClickEvent | JQuery<HTMLElement>, category: FeedbackToolbarCategory): JQuery {
    const isClickEvent = 'currentTarget' in target

    if (isClickEvent)
      return $(target.currentTarget).closest('.toolbar-submenu')

    let menuId: FeedbackClearOperationType | null = null
    switch (category) {
      case FeedbackToolbarCategory.UserType:
        menuId = FeedbackClearOperationType.ClearTypes
        break
      case FeedbackToolbarCategory.ContentTag:
        menuId = FeedbackClearOperationType.ClearTags
        break
      case FeedbackToolbarCategory.ResolutionStatus:
        menuId = FeedbackClearOperationType.ClearStatus
    }

    return target.find(`.toolbar-submenu:has(.toolbar-submenu-item[data-id="${menuId}"])`) || $()
  }

  handleAction(
    $toolbarMenu: JQuery,
    $discussionItem: JQuery,
    actionType: FeedbackActionType | null,
    category: FeedbackToolbarCategory,
    id: string,
    type: 'clear' | 'maker',
    remark: string = '',
  ): void {
    const config = CATEGORY_CONFIG[category]

    // 1-1. 批量清除存储状态
    if (type === 'clear') {
      Object.values(config.enumType).forEach((statType) => {
        this.pageHandler.storages.greasyFork.updateStorageItem(config.storagePath, statType, id, UpdateOperation.Remove, remark)
      })
    }
    // 1-2. 更新存储状态
    else if (type === 'maker') {
      this.pageHandler.storages.greasyFork.updateStorageItem(config.storagePath, actionType!, id, UpdateOperation.Add, remark)
    }

    // 2. 更新UI
    this.updateElementUI($discussionItem, id, category)
    this.updateToolbarMenu($toolbarMenu, category)

    // 3. 更新标签
    this.addTag()

    // 4. 更新选项计数
    this.filter?.updateOptionCounts(category, this.calculateCounts(category))
    this.applyFilters()
  }

  /**
   * 添加控制项
   */
  addControls(): void {
    const $container = $('.script-discussion-list')

    // 创建实例
    this.checkbox = new Checkbox({
      id: 'feedback-controls',
      options: this.controls_config,
      showSelectAll: false,
      onChange: (value: string, isChecked: boolean) => this.handleControlChange(value as ControlsType, isChecked),
    })

    $container?.prepend(this.checkbox.render())

    if (!$container || !$container.length)
      return

    this.checkbox?.mount($container)
  }

  /**
   * 处理控制项变化
   * @param action 动作名称
   * @param isChecked 是否选中
   */
  handleControlChange(action: ControlsType, isChecked: boolean): void {
    this.controls[action] = isChecked
    switch (action) {
      case ControlsType.hideNegative:
        this.hideNegativeFeedback()
        break
      case ControlsType.hideMalicious:
        this.hideMaliciousFeedback()
        break
      case ControlsType.hideBlacklist:
        this.hideBlacklistFeedback()
        break
    }
  }

  /**
   * 隐藏差评
   */
  private hideNegativeFeedback(): void {
    const $element = $(`${this.itemFullSelector}[${FeedbackDataMarkerType.MarkerTags}="${FeedbackTagType.Negative}"]`)
    this.handleHide($element, !this.controls.hideNegative)
  }

  /**
   * 隐藏恶意反馈
   */
  private hideMaliciousFeedback(): void {
    const $element = $(`${this.itemFullSelector}[${FeedbackDataMarkerType.MarkerTags}="${FeedbackTagType.Malicious}"]`)
    this.handleHide($element, !this.controls.hideMalicious)
  }

  /**
   * 隐藏黑名单用户的反馈
   */
  private hideBlacklistFeedback(): void {
    const $element = $(`${this.itemFullSelector}[${FeedbackDataMarkerType.MarkerTypes}="${GreasyForkUserType.Blacklisted}"]`)
    this.handleHide($element, !this.controls.hideBlacklist)
  }

  /**
   * 处理隐藏元素
   */
  handleHide($element: JQuery<HTMLElement>, show: boolean): void {
    ToolKit.dom.showControl($element, { show })
  }

  /**
   * 获取唯一 ID
   */
  private getUniqueId($element: JQuery): string {
    const discussionId = this.getDiscussionId($element)
    const scriptId = this.pageHandler.services.greasyFork.getScriptId()
    return discussionId.length > 0 && scriptId.length > 0 ? `${scriptId}#${discussionId}` : ''
  }

  /**
   * 获取讨论 ID
   */
  private getDiscussionId($element: JQuery): string {
    const discussionUrl = $element.find('.discussion-title').attr('href') || ''
    return this.extractDiscussionIdFromUrl(discussionUrl)
  }

  /**
   * 从 URL 中提取讨论 ID
   */
  private extractDiscussionIdFromUrl(url: string): string {
    const match = url.match(/\/discussions\/(\d+)/)
    const discussionId = match ? match[1] : ''

    if (discussionId.length === 0)
      logger.error(`[${this.name}] 讨论 ID 提取失败`)

    return discussionId
  }

  applyConfig(config: Partial<Config>): void {
    super.updateConfig(config)

    logger.info(`[${this.name}] Config updated and apply`, this.config)
  }

  /**
   * 获取标签样式
   */
  public static getTagStyles() {
    return `
.feedback-tags-container {
  height: 30px;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
  padding: 10px !important;
  
  .feedback-tag {
    padding: 4px 8px;
    border-radius: 12px;
    font-size: 12px;
    font-weight: 600;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    display: flex;
    align-items: center;
    
    .tag-icon {
      display: inline-block;
      margin-right: 2px;
      font-size: 14px;
    }
    
    .tag-text {
      display: inline-block;
    }
  }
}
    `
  }

  getStyles(): string {
    return ``
  }
}
